<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring依赖注入方式详解 | 技术小馆</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background-color: #f8f9fa;
            border-left: 4px solid #6e8efb;
        }
        .injection-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .hover-scale {
            transition: transform 0.3s ease;
        }
        .hover-scale:hover {
            transform: scale(1.02);
        }
        .text-gradient {
            background: linear-gradient(90deg, #6e8efb, #a777e3);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
        }
        .divider {
            height: 1px;
            background: linear-gradient(90deg, transparent, rgba(0,0,0,0.1), transparent);
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 md:py-32">
        <div class="container mx-auto max-w-6xl">
            <div class="flex flex-col items-center text-center">
                <h1 class="text-4xl md:text-5xl font-bold mb-6 font-serif">Spring 依赖注入艺术</h1>
                <p class="text-xl md:text-2xl max-w-3xl mb-8 opacity-90">探索 Spring 框架中优雅的依赖管理方式</p>
                <div class="flex space-x-4">
                    <a href="#intro" class="px-6 py-3 bg-white text-indigo-600 rounded-full font-medium hover:bg-opacity-90 transition">开始探索</a>
                    <a href="#types" class="px-6 py-3 border-2 border-white rounded-full font-medium hover:bg-white hover:bg-opacity-10 transition">注入方式</a>
                </div>
            </div>
        </div>
    </section>

    <!-- Introduction -->
    <section id="intro" class="py-16 px-4">
        <div class="container mx-auto max-w-6xl">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-8 md:mb-0 md:pr-10">
                    <h2 class="text-3xl font-bold mb-6 font-serif">什么是依赖注入？</h2>
                    <p class="text-lg mb-6">依赖注入(Dependency Injection, DI)是Spring框架的核心特性之一，它是一种设计模式，通过将对象依赖关系的创建和管理交给外部容器来实现控制反转(IoC)。</p>
                    <p class="text-lg mb-6">这种机制减少了组件间的耦合度，提高了代码的可测试性和可维护性，是构建松耦合、高内聚应用程序的关键。</p>
                    <div class="flex items-center text-indigo-600 font-medium">
                        <i class="fas fa-arrow-circle-right mr-2"></i>
                        <span>继续了解各种注入方式</span>
                    </div>
                </div>
                <div class="md:w-1/2">
                    <div class="bg-white rounded-xl shadow-lg overflow-hidden hover-scale">
                        <div class="mermaid p-6">
                            graph LR
                            A[客户端] -->|依赖| B[服务]
                            C[容器] -->|注入| A
                            style A fill:#6e8efb,color:#fff
                            style B fill:#a777e3,color:#fff
                            style C fill:#4ade80,color:#fff
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Divider -->
    <div class="divider my-8"></div>

    <!-- Injection Types -->
    <section id="types" class="py-16 px-4">
        <div class="container mx-auto max-w-6xl">
            <h2 class="text-3xl font-bold mb-12 text-center font-serif">Spring 注入方式详解</h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <!-- Constructor Injection -->
                <div class="injection-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300">
                    <div class="p-6">
                        <div class="flex items-center mb-4">
                            <div class="w-12 h-12 rounded-full bg-indigo-100 text-indigo-600 flex items-center justify-center mr-4">
                                <i class="fas fa-cubes text-xl"></i>
                            </div>
                            <h3 class="text-2xl font-bold text-gray-800">构造函数注入</h3>
                        </div>
                        <p class="text-gray-600 mb-6">通过类的构造函数参数来注入依赖项，是最推荐的注入方式。</p>
                        <div class="code-block p-4 rounded mb-6 overflow-x-auto">
                            <pre><code class="language-java">@Autowired
public ExampleService(ExampleRepository repository) {
    this.repository = repository;
}</code></pre>
                        </div>
                        <div class="flex flex-wrap gap-2">
                            <span class="px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full text-sm">强依赖</span>
                            <span class="px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full text-sm">不可变</span>
                            <span class="px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full text-sm">推荐</span>
                        </div>
                    </div>
                </div>

                <!-- Setter Injection -->
                <div class="injection-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300">
                    <div class="p-6">
                        <div class="flex items-center mb-4">
                            <div class="w-12 h-12 rounded-full bg-purple-100 text-purple-600 flex items-center justify-center mr-4">
                                <i class="fas fa-exchange-alt text-xl"></i>
                            </div>
                            <h3 class="text-2xl font-bold text-gray-800">Setter方法注入</h3>
                        </div>
                        <p class="text-gray-600 mb-6">通过setter方法注入依赖项，适合可选依赖或需要重新设置依赖的情况。</p>
                        <div class="code-block p-4 rounded mb-6 overflow-x-auto">
                            <pre><code class="language-java">@Autowired
public void setExampleRepository(ExampleRepository repository) {
    this.repository = repository;
}</code></pre>
                        </div>
                        <div class="flex flex-wrap gap-2">
                            <span class="px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm">可选依赖</span>
                            <span class="px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm">可重新设置</span>
                        </div>
                    </div>
                </div>

                <!-- Field Injection -->
                <div class="injection-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300">
                    <div class="p-6">
                        <div class="flex items-center mb-4">
                            <div class="w-12 h-12 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center mr-4">
                                <i class="fas fa-code text-xl"></i>
                            </div>
                            <h3 class="text-2xl font-bold text-gray-800">字段注入</h3>
                        </div>
                        <p class="text-gray-600 mb-6">直接在字段上使用注解注入依赖，简洁但不利于测试和灵活性。</p>
                        <div class="code-block p-4 rounded mb-6 overflow-x-auto">
                            <pre><code class="language-java">@Autowired
private ExampleRepository repository;</code></pre>
                        </div>
                        <div class="flex flex-wrap gap-2">
                            <span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm">简洁</span>
                            <span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm">不推荐</span>
                        </div>
                    </div>
                </div>

                <!-- Interface Injection -->
                <div class="injection-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300">
                    <div class="p-6">
                        <div class="flex items-center mb-4">
                            <div class="w-12 h-12 rounded-full bg-green-100 text-green-600 flex items-center justify-center mr-4">
                                <i class="fas fa-project-diagram text-xl"></i>
                            </div>
                            <h3 class="text-2xl font-bold text-gray-800">接口注入</h3>
                        </div>
                        <p class="text-gray-600 mb-6">通过特定接口注入依赖，较为灵活但使用较少。</p>
                        <div class="code-block p-4 rounded mb-6 overflow-x-auto">
                            <pre><code class="language-java">@Autowired
public void setExampleRepository(ExampleRepository repository) {
    this.repository = repository;
}</code></pre>
                        </div>
                        <div class="flex flex-wrap gap-2">
                            <span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">灵活</span>
                            <span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">复杂</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Best Practices -->
    <section class="py-16 px-4 bg-gray-50">
        <div class="container mx-auto max-w-6xl">
            <div class="text-center mb-12">
                <h2 class="text-3xl font-bold font-serif">最佳实践指南</h2>
                <p class="text-xl text-gray-600 mt-2">如何选择合适的注入方式</p>
            </div>
            
            <div class="grid md:grid-cols-3 gap-8">
                <div class="bg-white p-8 rounded-xl shadow-sm hover-scale">
                    <div class="w-16 h-16 bg-indigo-100 rounded-full flex items-center justify-center mb-6">
                        <i class="fas fa-check-circle text-indigo-600 text-2xl"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-4">优先使用构造函数注入</h3>
                    <p class="text-gray-600">对于必需的依赖项，优先使用构造函数注入，因为它可以确保对象在构造时就具备所有必需依赖，并且使依赖不可变。</p>
                </div>
                
                <div class="bg-white p-8 rounded-xl shadow-sm hover-scale">
                    <div class="w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mb-6">
                        <i class="fas fa-exclamation-triangle text-purple-600 text-2xl"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-4">避免过度使用字段注入</h3>
                    <p class="text-gray-600">尽管字段注入使用简单，但它隐藏了类的依赖关系，不利于单元测试，并可能导致空指针异常。</p>
                </div>
                
                <div class="bg-white p-8 rounded-xl shadow-sm hover-scale">
                    <div class="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mb-6">
                        <i class="fas fa-balance-scale text-blue-600 text-2xl"></i>
                    </div>
                    <h3 class="text-xl font-bold mb-4">合理选择注入方式</h3>
                    <p class="text-gray-600">根据依赖项的性质选择合适的注入方式：必需依赖用构造函数，可选依赖用Setter方法，特定场景才考虑其他方式。</p>
                </div>
            </div>
        </div>
    </section>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12 px-4">
        <div class="container mx-auto max-w-6xl">
            <div class="flex flex-col items-center">
                <div class="text-2xl font-bold text-white mb-4">技术小馆</div>
                <a href="http://www.yuque.com/jtostring" class="text-gray-400 hover:text-white transition">www.yuque.com/jtostring</a>
                <div class="mt-6 flex space-x-4">
                    <a href="#" class="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-indigo-600 transition">
                        <i class="fab fa-github"></i>
                    </a>
                    <a href="#" class="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-blue-500 transition">
                        <i class="fab fa-twitter"></i>
                    </a>
                    <a href="#" class="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-red-500 transition">
                        <i class="fab fa-youtube"></i>
                    </a>
                </div>
            </div>
        </div>
    </footer>

    <script>
        // 初始化Mermaid图表
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            fontFamily: 'Noto Sans SC, sans-serif',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>